package com.example.utils;

import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

public class HttpRequest {

    public static String sendGet(String url) {
        String result = "";
        BufferedReader in = null;
        try{
            String urlNameString = url;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");

            // connection.setRequestProperty("user-agent",
            // "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            // // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            // Map<String, List<String>> map = connection.getHeaderFields();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null){
                result += line;
            }
        }
        catch (Exception e){
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally{
            try{
                if (in != null){
                    in.close();
                }
            }
            catch (Exception e2){
                e2.printStackTrace();
            }
        }
        return result;
    }


    public static String sendGet(String url, String charset) {
        String result = "";
        BufferedReader in = null;
        try{
            String urlNameString = url;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");

            // connection.setRequestProperty("user-agent",
            // "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            // // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            // Map<String, List<String>> map = connection.getHeaderFields();

            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));
            String line;
            while ((line = in.readLine()) != null){
                result += line;
            }
        }
        catch (Exception e){
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally{
            try{
                if (in != null){
                    in.close();
                }
            }
            catch (Exception e2){
                e2.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try{
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null){
                result += line;
            }
        }
        catch (Exception e){
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally{
            try{
                if (out != null){
                    out.close();
                }
                if (in != null){
                    in.close();
                }
            }
            catch (IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }


    /**
     * HttpClient端模拟
     *
     * @Title: httpClientPrint
     * @Description: 发送URL
     * @param url
     * @return
     * @throws Exception
     * @createdBy:Administrator
     * @createaAt:2015年10月15日下午3:24:25
     */
    public static String httpClientPrint(String url) throws Exception {
        String respHtml = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpGet httpGet = new HttpGet(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(20000).setConnectionRequestTimeout(20000).setSocketTimeout(20000).build();
        httpGet.setConfig(requestConfig);
        CloseableHttpResponse response = httpclient.execute(httpGet);

        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK){
            HttpEntity respEnt = response.getEntity();
            respHtml = EntityUtils.toString(respEnt, "UTF-8");
        }
        return respHtml;
    }


    /**
     * HttpClient POST发送XML
     *
     * @Title: sendXMLDataByPost
     * @Description: 发送XML
     * @param url
     * @param xmlData
     * @return
     * @throws Exception
     * @createdBy:Administrator
     * @createaAt:2016年5月17日上午11:11:04
     */
    public static String sendXMLDataByPost(String url, String xmlData) throws Exception {
        String respXml = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // Send data by post method in HTTP protocol,use HttpPost instead of
        // PostMethod which was occurred in former version
        HttpPost post = new HttpPost(url);
        // Construct a string entity
        StringEntity entity = new StringEntity(xmlData, "UTF-8");
        // Set XML entity
        post.setEntity(entity);
        // Set content type of request header
        post.setHeader("Content-Type", "text/xml;charset=UTF-8");
        // Execute request and get the response
        HttpResponse response = httpclient.execute(post);
        // Response Header - StatusLine - status code
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK){
            HttpEntity respEnt = response.getEntity();
            respXml = EntityUtils.toString(respEnt, "UTF-8");
        }
        return respXml;
    }


    public static String httpClientPost(String url, String body) throws Exception {
        String respHtml = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
        httpPost.setHeader("Accept", "application/json");
        StringEntity entity = new StringEntity(body, ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        CloseableHttpResponse response = httpclient.execute(httpPost);

        int statusCode = response.getStatusLine().getStatusCode();
//		if (statusCode == HttpStatus.SC_OK){
        HttpEntity respEnt = response.getEntity();
        respHtml = EntityUtils.toString(respEnt, "UTF-8");
//		}
        return respHtml;
    }


    public static String httpClientPostWwwurlencoded(String url, String body, Map<String, String> headerMap)
            throws Exception {
        String respHtml = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        httpPost.setHeader("Accept", "application/x-www-form-urlencoded");
        headerMap.entrySet().stream().forEach(m -> {
            httpPost.setHeader(m.getKey(), m.getValue());
        });
        StringEntity entity = new StringEntity(body,
                ContentType.create("application/x-www-form-urlencoded", Consts.UTF_8));
        httpPost.setEntity(entity);
        CloseableHttpResponse response = httpclient.execute(httpPost);

        int statusCode = response.getStatusLine().getStatusCode();
        // if (statusCode == HttpStatus.SC_OK){
        HttpEntity respEnt = response.getEntity();
        respHtml = EntityUtils.toString(respEnt, "UTF-8");
        // }
        return respHtml;
    }


    public static String httpClientPost(String url) throws Exception {
        String respHtml = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
        httpPost.setHeader("Accept", "application/json");
        CloseableHttpResponse response = httpclient.execute(httpPost);

        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK){
            HttpEntity respEnt = response.getEntity();
            respHtml = EntityUtils.toString(respEnt, "UTF-8");
        }
        return respHtml;
    }


    public static String httpClientGet(String url) throws Exception {
        String respHtml = "";
        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpGet httpGet = new HttpGet(url);
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();
        httpGet.setConfig(requestConfig);
        httpGet.setHeader("Content-Type", "application/json;charset=UTF-8");
        httpGet.setHeader("Accept", "application/json");
        CloseableHttpResponse response = httpclient.execute(httpGet);

        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK){
            HttpEntity respEnt = response.getEntity();
            respHtml = EntityUtils.toString(respEnt, "UTF-8");
        }
        return respHtml;
    }


    public static CloseableHttpClient createHttpClient() {
        RequestConfig.Builder builder = RequestConfig.custom();
        builder.setConnectTimeout(10000);// 设置连接超时时间，单位毫秒
        builder.setConnectionRequestTimeout(10000);// 设置从connect
        // Manager获取Connection
        // 超时时间，单位毫秒。这个属性是新加的属性，因为目前版本是可以共享连接池的。
        builder.setSocketTimeout(20000);// 请求获取数据的超时时间，单位毫秒。
        // 如果访问一个接口，多少时间内无法返回数据，就直接放弃此次调用。
        RequestConfig defaultRequestConfig = builder.setCookieSpec(CookieSpecs.STANDARD_STRICT).setExpectContinueEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        CloseableHttpClient httpClient = httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig).build();
        return httpClient;
    }


    public static String sendPostByOutWrite(String url, String param) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        String result = "";
        try{
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            // 发送请求参数
            out.write(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
            String line;
            while ((line = in.readLine()) != null){
                result += line;
            }
        }
        catch (Exception e){
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally{
            try{
                if (out != null){
                    out.close();
                }
                if (in != null){
                    in.close();
                }
            }
            catch (IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }


    /**
     * post请求(用于key-value格式的参数)
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map params) {

        BufferedReader in = null;
        try{
            // 定义HttpClient
            HttpClient client = new DefaultHttpClient();
            // 实例化HTTP方法
            HttpPost request = new HttpPost();
            request.setURI(new URI(url));

            // 设置参数
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            for (Iterator iter = params.keySet().iterator(); iter.hasNext();){
                String name = (String) iter.next();
                String value = String.valueOf(params.get(name));
                nvps.add(new BasicNameValuePair(name, value));
            }
            request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

            HttpResponse response = client.execute(request);
            int code = response.getStatusLine().getStatusCode();
            if (code == 200){ // 请求成功
                in = new BufferedReader(new InputStreamReader(response.getEntity()
                        .getContent(), "utf-8"));
                StringBuffer sb = new StringBuffer("");
                String line = "";
                String NL = System.getProperty("line.separator");
                while ((line = in.readLine()) != null){
                    sb.append(line + NL);
                }

                in.close();

                return sb.toString();
            }
            else{ //
                System.out.println("状态码：" + code);
                return null;
            }
        }
        catch (Exception e){
            e.printStackTrace();

            return null;
        }
    }



    public static String httpRequestPut(String postUrl, String putData) {
        try{
            // 发送POST请求
            URL url = new URL(postUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("PUT");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Length", "" + putData.length());
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            out.write(putData);
            out.flush();
            out.close();
            // 获取响应状态
            if (conn.getResponseCode() != HttpURLConnection.HTTP_OK){
                System.out.println("connect failed!");
                return "";
            }
            // 获取响应内容体
            String line , result = "";
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            while ((line = in.readLine()) != null){
                result += line + "\n";
            }
            in.close();
            return result;
        }
        catch (IOException e){
            e.printStackTrace(System.out);
        }
        return "";
    }


    public static String httpPostRaw(String postUrl, String postData) {
        try{
            // 发送POST请求
            URL url = new URL(postUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Length", "" + postData.length());
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            out.write(postData);
            out.flush();
            out.close();
            // 获取响应状态
            if (conn.getResponseCode() != HttpURLConnection.HTTP_OK){
                System.out.println("connect failed!");
                return "";
            }
            // 获取响应内容体
            String line , result = "";
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            while ((line = in.readLine()) != null){
                result += line + "\n";
            }
            in.close();
            return result;
        }
        catch (IOException e){
            e.printStackTrace(System.out);
        }
        return "";
    }
}
